import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
import 'package:kq_flutter_core_widget/utils/kq_screen_util.dart';
import 'package:get/get_state_manager/get_state_manager.dart';
import '../../resources/kq_theme_colors.dart';
import 'base/kq_chart_model.dart';

class ChartLineModel extends GetxController {
  ///通用图标布局
  KqChartModel chartModel;

  ///输入数据集合
  List<List<ChartLineValue>> chartArray;

  ///线颜色数组与chartLineArray一一对应，在ChartBarValue中barColor为null时使用
  List<Color>? lineColors;

  ///遮罩颜色数组与chartLineArray一一对应，在ChartBarValue中barColor为null时使用
  List<List<Color>>? shaderColors;

  ChartLineModel({
    required this.chartModel,
    this.chartArray = const [],
    this.lineColors,
    this.shaderColors,
  });
  /**以下均为内部计算无需传入 */
  ///实际高度
  double yHeight = 0;

  ///实际宽度
  double xWidth = 0;

  int maxCross = 0;

  double maxHeight = 0;

  ///平均线坐标数组
  List<double> avgYPointList = [];

  ///横坐标数组
  List<double> xList = [];

  ///横坐标内容
  List xValue = [];

  ///纵坐标数组
  List yList = [];

  ///纵坐标内容
  List yValue = [];

  ///横坐标间距
  double crossSpacing = 0;

  ///横坐标显示内容个数不为0时，使用传入需要显示内容点的对应下标
  List<int> crossShowList = [];

  void setChartData() {
    getAbscissaList();
    getOrdinateList();
  }

  void _initData() {
    chartModel.initData();
    chartModel.xColor = chartModel.xColor ?? KqThemeColors.text8C;
    chartModel.yColor = chartModel.yColor ?? KqThemeColors.text8C;
    chartModel.axisColor = chartModel.axisColor ?? KqThemeColors.bgF0;
    chartModel.dividerColor = chartModel.dividerColor ?? KqThemeColors.bgF0;
    maxCross = 0;
    maxHeight = 0;
    crossShowList = [];
    avgYPointList = [];
    yHeight = chartModel.sizeHeight -
        chartModel.yTop! -
        chartModel.yBottom! -
        chartModel.yAxisTop!;
    xWidth = chartModel.sizeWidth - chartModel.xLeft! - chartModel.xRight!;
  }

  ///设置内容
  void setValueList(List<List<ChartLineValue>> list, KqChartModel chartModel) {
    this.chartModel = chartModel;
    _initData();
    int index = 0;
    for (var i = 0; i < list.length; i++) {
      List<ChartLineValue> e = list[i];
      index = maxCross > e.length ? index : i;
      maxCross = maxCross > e.length ? maxCross : e.length;
    }

    chartArray = list;
    if (!chartModel.isFixMaxY) {
      chartArray.map((List<ChartLineValue> e) {
        e.map((ChartLineValue value) {
          double y = double.parse(value.yValue);
          if (chartModel.maxY > y) {
            maxHeight =
                maxHeight > chartModel.maxY ? maxHeight : chartModel.maxY;
          } else {
            maxHeight = maxHeight > y ? maxHeight : y;
          }
        }).toList();
      }).toList();
    } else {
      maxHeight = chartModel.maxY;
    }

    var maxYText = TextPainter(
        textAlign: TextAlign.right,
        ellipsis: '.',
        maxLines: 1,
        text: TextSpan(
            text: maxHeight.toString(),
            style: TextStyle(fontSize: chartModel.yFont)),
        textDirection: TextDirection.rtl)
      ..layout();
    chartModel.xLeft = chartModel.xLeft == 40.r
        ? maxYText.size.width + chartModel.yFont!
        : chartModel.xLeft;

    setChartData();

    xValue = [];
    if (list.length > index) {
      List<ChartLineValue> maxLine = list[index];
      maxLine.map((e) => xValue.add(e.xValue)).toList();
    }
    if (chartModel.avgValues!.isNotEmpty) {
      for (var i = 0; i < chartModel.avgValues!.length; i++) {
        double avgYPoint = double.parse(chartModel.avgValues![i]);
        avgYPointList.add(((maxHeight - avgYPoint) / maxHeight) * yHeight +
            chartModel.yTop! +
            chartModel.yAxisTop!);
      }
      chartArray.map((e) {
        setXPointToValueList(e);
        setYPointToValueList(e);
      }).toList();
    } else {
      chartArray.map((e) {
        setXPointToValueList(e);
        setYPointToValueList(e);
        getAvgValuePointList(e);
      }).toList();
    }
  }

  ///获取横坐标数组
  void getAbscissaList() {
    if (maxCross < 2) {
      crossSpacing = xWidth - chartModel.initialPointX;
    } else {
      crossSpacing = (xWidth - chartModel.initialPointX) / (maxCross - 1);
    }
    xList = [];
    for (int i = 0; i < (maxCross < 2 ? 2 : maxCross); i++) {
      double absPoint =
          crossSpacing * i + chartModel.xLeft! + chartModel.initialPointX;
      xList.add(absPoint);
    }
  }

  ///获取纵坐标数组
  void getOrdinateList() {
    double rowSpacing = yHeight / (chartModel.rowCount - 1);
    double ySpac = maxHeight / (chartModel.rowCount - 1);
    yList = [];
    yValue = [];
    for (int i = 0; i < chartModel.rowCount; i++) {
      yList.add(rowSpacing * i + chartModel.yTop! + chartModel.yAxisTop!);
      if (i == 0) {
        int maxYvalue = (maxHeight * 10).ceil();
        String value = (maxYvalue / 10).toString();
        yValue.add(Decimal.parse(value).toString());
      } else {
        double yDouble = ySpac * (chartModel.rowCount - i - 1);
        String value = (yDouble.toStringAsFixed(1)).toString();
        yValue.add(Decimal.parse(value).toString());
      }
    }
  }

  ///获取平均线数组
  void getAvgValuePointList(List<ChartLineValue> valueList) {
    if (valueList.isNotEmpty) {
      double sum = valueList.fold(
          0,
          (double preValue, ChartLineValue data) =>
              preValue + double.parse(data.yValue));
      double avgYPoint = sum / valueList.length;
      String value = (avgYPoint.toStringAsFixed(2)).toString();
      chartModel.avgValues!.add(Decimal.parse(value).toString());
      avgYPointList.add(((maxHeight - avgYPoint) / maxHeight) * yHeight +
          chartModel.yTop! +
          chartModel.yAxisTop!);
    }
  }

  ///给内容数组赋值横坐标值
  void setXPointToValueList(List<ChartLineValue> valueList) {
    if (valueList.length > 1) {
      for (int i = 0; i < valueList.length; i++) {
        ChartLineValue value = valueList[i];
        value.xPoint = xList[i];
        // xValue.add(value.xValue);
      }
      if (chartModel.crossCount != 0 &&
          (chartModel.crossShowList == null ||
              chartModel.crossShowList!.isEmpty)) {
        crossShowList = [];
        double interval = maxCross / (chartModel.crossCount - 1);
        for (int i = 0; i < chartModel.crossCount; i++) {
          if (i == 0) {
            crossShowList.add(0);
          } else if (i == chartModel.crossCount - 1) {
            crossShowList.add(maxCross - 1);
          } else if (i < maxCross) {
            crossShowList.add((interval * i).truncate());
          }
        }
      } else {
        crossShowList = chartModel.crossShowList ?? [];
      }
    } else {
      if (valueList.isNotEmpty) {
        ChartLineValue value = valueList.first;
        value.xPoint = xList.first + xWidth / 2;
        // xValue.add(value.xValue);
      }
    }
  }

  ///给内容数组赋值纵坐标值
  void setYPointToValueList(List<ChartLineValue> valueList) {
    for (int i = 0; i < valueList.length; i++) {
      ChartLineValue value = valueList[i];
      double yHValue = double.tryParse(value.yValue) ?? 0;
      value.yPoint = ((maxHeight - yHValue) / maxHeight) * yHeight +
          chartModel.yTop! +
          chartModel.yAxisTop!;
    }
  }
}

class ChartLineValue {
  String xValue;
  String yValue;

  ///文案样式
  TextStyle style;

  ///当点击或者滑动到该区域时是否显示文案，只针对isShowValue=false且isShowClickValue或isShowSlideValue为True才会被使用
  bool isShow;

  ///是否显示内容点的分割线
  bool isCountDivider;

  ///内容分割线的颜色
  Color dividerColor;

  ///分割线是否为实线，默认为false
  bool dividerLineSolid;

  ///线的宽度,默认1
  double lineWidth;

  ///以下为自动计算，无需传入
  double xPoint = 0;
  double yPoint = 0;
  ChartLineValue({
    required this.xValue,
    required this.yValue,
    this.style = const TextStyle(fontSize: 12, color: KqThemeColors.text59),
    this.isCountDivider = false,
    this.dividerLineSolid = false,
    this.dividerColor = KqThemeColors.textLightBlue,
    this.isShow = false,
    this.lineWidth = 1,
  });
}
